﻿#include "HnrjitProgress.h"
#include "HnrjitContainer.h"

CHnrjitProgress::CHnrjitProgress()
	: CHnrjitControl()
	, m_lMaximum(100)
	, m_lMinimum(0)
	, m_lValue(0)
	, m_isShowPercent(FALSE)
{
	ZeroMemory(&m_tSplitSizes, sizeof(m_tSplitSizes));
}

void CHnrjitProgress::SetAttribute(const TiXmlElement* pxElement, HZIP hZipRes /*= NULL*/)
{
	CHnrjitControl::SetAttribute(pxElement, hZipRes);

	const CHAR* pszValue;
	if (pszValue = pxElement->Attribute("Maximum"))
	{
		LONG lMaximum = strtol(pszValue, NULL, 10);
		SetMaximum(lMaximum);
	}
	if (pszValue = pxElement->Attribute("Minimum"))
	{
		LONG lMinimum = strtol(pszValue, NULL, 10);
		SetMinimum(lMinimum);
	}
	if (pszValue = pxElement->Attribute("Value"))
	{
		LONG lValue = strtol(pszValue, NULL, 10);
		SetValue(lValue);
	}
	if (pszValue = pxElement->Attribute("SplitSizes"))
	{
		CHAR* pszEndPtr = NULL;
		m_tSplitSizes.wLeftSize = (WORD) strtol(pszValue, &pszEndPtr, 10);
		if (pszEndPtr)
		{
			m_tSplitSizes.wFullSize = (WORD) strtol(pszEndPtr + 1, &pszEndPtr, 10);
			if (pszEndPtr)
			{
				m_tSplitSizes.wSliderSize = (WORD) strtol(pszEndPtr + 1, &pszEndPtr, 10);
				if (pszEndPtr)
				{
					m_tSplitSizes.wEmptySize = (WORD) strtol(pszEndPtr + 1, &pszEndPtr, 10);
					if (pszEndPtr)
					{
						m_tSplitSizes.wRightSize = (WORD) strtol(pszEndPtr + 1, NULL, 10);
					}
				}
			}
		}
		Invalidate(m_rcGeometry);
	}
	if (pszValue = pxElement->Attribute("ShowPercent"))
	{
		if (strcmp(pszValue, "true") == 0)
		{
			SetShowPercent(TRUE);
		}
	}
}

LONG CHnrjitProgress::GetMaximum() const
{
	return m_lMaximum;
}

bool CHnrjitProgress::SetMaximum(LONG lMaximum)
{
	ATLASSERT(m_dwThreadID == GetCurrentThreadId());
	if (lMaximum <= m_lMinimum) return false; // 无效的最大值

	if (lMaximum != m_lMaximum)
	{
		m_lMaximum = lMaximum;
		if (m_lValue > m_lMaximum)
		{
			// 修正进度条数值
			m_lValue = m_lMaximum;
		}
		Invalidate(m_rcGeometry);
	}

	return true;
}

LONG CHnrjitProgress::GetMinimum() const
{
	return m_lMinimum;
}

bool CHnrjitProgress::SetMinimum(LONG lMinimum)
{
	ATLASSERT(m_dwThreadID == GetCurrentThreadId());
	if (lMinimum >= m_lMaximum) return false; // 无效的最小值

	if (lMinimum != m_lMinimum)
	{
		m_lMinimum = lMinimum;
		if (m_lValue < m_lMinimum)
		{
			m_lValue = m_lMinimum;
		}
		Invalidate(m_rcGeometry);
	}

	return true;
}

LONG CHnrjitProgress::GetValue() const
{
	return m_lValue;
}

void CHnrjitProgress::SetValue(LONG lValue)
{
	ATLASSERT(m_dwThreadID == GetCurrentThreadId());
	if (lValue > m_lMaximum)
	{
		lValue = m_lMaximum;
	}
	else if (lValue < m_lMinimum)
	{
		lValue = m_lMinimum;
	}

	if (lValue != m_lValue)
	{
		m_lValue = lValue;
		Invalidate(m_rcGeometry);
	}
}

const SplitSizes& CHnrjitProgress::GetSplitSizes() const
{
	return m_tSplitSizes;
}

void CHnrjitProgress::SetSplitSizes(const SplitSizes& tSplitSizes)
{
	ATLASSERT(m_dwThreadID == GetCurrentThreadId());
	m_tSplitSizes = tSplitSizes;
	Invalidate(m_rcGeometry);
}

BOOL CHnrjitProgress::IsShowPercent() const
{
	return m_isShowPercent;
}

void CHnrjitProgress::SetShowPercent(BOOL isShowPercent)
{
	ATLASSERT(m_dwThreadID == GetCurrentThreadId());
	m_isShowPercent = isShowPercent;
	Invalidate(m_rcGeometry);
}

void CHnrjitProgress::DrawTitle(HDC hdc, const CRect& rcGeometry, ControlStatus iControlStatus)
{
	if (m_isShowPercent)
	{
		ATLASSERT(iControlStatus == kNormal || iControlStatus == kActivated || iControlStatus == kDisabled);

		TCHAR szProgressPercent[24];
		LONG lProgressValue = m_lValue - m_lMinimum;
		LONG lProgressLength = m_lMaximum - m_lMinimum;
		LONG lProgressPercent = (lProgressValue * 100) / lProgressLength;

		if (_stprintf_s(szProgressPercent, _countof(szProgressPercent), _T("%d %%"), lProgressPercent) != -1)
		{
			SelectObject(hdc, m_tagFont);
			SetTextColor(hdc, m_crForeColors[iControlStatus]);
			if ((m_nTextAlign & DT_VCENTER) && (m_nTextAlign & DT_WORDBREAK))
			{
				CRect rcControl = rcGeometry;
				CRect rcVCenter = rcControl;
				int dwTextHeight = DrawText(hdc, m_strTitle, -1, rcVCenter, (m_nTextAlign & ~DT_VCENTER) | DT_CALCRECT); // 获得文本高度
				rcControl.DeflateRect(0, (rcControl.Height() - dwTextHeight) / 2); // 改变矩形高度

				DrawText(hdc, szProgressPercent, -1, rcControl, m_nTextAlign & ~DT_VCENTER);
			}
			else
			{
				DrawText(hdc, szProgressPercent, -1, const_cast<CRect& >(rcGeometry), m_nTextAlign);
			}
		}
	}
	else
	{
		CHnrjitControl::DrawTitle(hdc, rcGeometry, iControlStatus);
	}
}

void CHnrjitProgress::DrawRect(HDC hdc, const CRect& rcGeometry, ControlStatus iControlStatus)
{
	CHnrjitControl::DrawRect(hdc, rcGeometry, iControlStatus);
}

void CHnrjitProgress::DrawImage(HDC hdc, const CRect& rcGeometry, ControlStatus iControlStatus)
{
	ATLASSERT(m_spBackIcons[iControlStatus] != NULL);
	ATLASSERT(iControlStatus == kNormal || iControlStatus == kActivated || iControlStatus == kDisabled);

	if (!m_isTransparent && !m_pContainer->IsTransparent())
	{
		ImageInfo ImgInfo;
		if (m_spBackIcons[iControlStatus]->GetImageInfo(&ImgInfo) == S_OK)
		{
			LONG lValue = m_lValue - m_lMinimum; // 进度条相对位置
			LONG lLength = m_lMaximum - m_lMinimum; // 进度条相对长度

			LONG lValidWidth = m_rcGeometry.Width() - m_tSplitSizes.wLeftSize - m_tSplitSizes.wRightSize; // 有效长度
			LONG lFullWidth = (lValue * lValidWidth) / lLength - m_tSplitSizes.wSliderSize / 2; // 滑块占一半
			LONG lEmptyWidth = lValidWidth - lFullWidth - m_tSplitSizes.wSliderSize; // 滑块占一半

			POINT destPoint = { m_rcGeometry.left, m_rcGeometry.top };
			POINT srcPoint = { 0, 0 };

			HDC hdcMemory = CreateCompatibleDC(hdc);
			if (hdcMemory)
			{
				HBITMAP hNewBitmap = CreateCompatibleBitmap(hdc, ImgInfo.Width, ImgInfo.Height);
				if (hNewBitmap)
				{
					HGDIOBJ hOldBitmap = SelectObject(hdcMemory, hNewBitmap);

					m_spBackIcons[iControlStatus]->Draw(hdcMemory, CRect(0, 0, ImgInfo.Width, ImgInfo.Height), NULL);

					// 绘制左边图片
					StretchBlt(hdc, destPoint.x, destPoint.y, m_tSplitSizes.wLeftSize, ImgInfo.Height,
						hdcMemory, srcPoint.x, srcPoint.y, m_tSplitSizes.wLeftSize, ImgInfo.Height, SRCCOPY);
					// 绘制满的图片
					if (lFullWidth > 0)
					{
						destPoint.x += m_tSplitSizes.wLeftSize;
						srcPoint.x += m_tSplitSizes.wLeftSize;
						StretchBlt(hdc, destPoint.x, destPoint.y, lFullWidth, ImgInfo.Height,
							hdcMemory, srcPoint.x, srcPoint.y, m_tSplitSizes.wFullSize, ImgInfo.Height, SRCCOPY);
					}
					// 绘制滑块图片
					destPoint.x += lFullWidth;
					srcPoint.x += m_tSplitSizes.wFullSize;
					StretchBlt(hdc, destPoint.x, destPoint.y, m_tSplitSizes.wSliderSize, ImgInfo.Height,
						hdcMemory, srcPoint.x, srcPoint.y, m_tSplitSizes.wSliderSize, ImgInfo.Height, SRCCOPY);
					// 绘制空的图片
					if (lEmptyWidth > 0)
					{
						destPoint.x += m_tSplitSizes.wSliderSize;
						srcPoint.x += m_tSplitSizes.wSliderSize;
						StretchBlt(hdc, destPoint.x, destPoint.y, lEmptyWidth, ImgInfo.Height,
							hdcMemory, srcPoint.x, srcPoint.y, m_tSplitSizes.wEmptySize, ImgInfo.Height, SRCCOPY);
					}
					// 绘制右边的图片
					destPoint.x += lEmptyWidth;
					srcPoint.x += m_tSplitSizes.wEmptySize;
					StretchBlt(hdc, destPoint.x, destPoint.y, m_tSplitSizes.wRightSize, ImgInfo.Height,
						hdcMemory, srcPoint.x, srcPoint.y, m_tSplitSizes.wRightSize, ImgInfo.Height, SRCCOPY);

					SelectObject(hdcMemory, hOldBitmap);
					DeleteObject(hNewBitmap);
				}
				DeleteDC(hdcMemory);
			}
		}
	}
}

void CHnrjitProgress::DrawControl(HDC hdc)
{
	CRect rcReference = CRect(GetLocation() + m_pContainer->GetLocation(), GetSize());

	ControlStatus iControlStatus = GetControlState();
	if (m_spBackIcons[iControlStatus])
	{
		DrawImage(hdc, rcReference, iControlStatus);
	}
	else
	{
		if (iControlStatus == kActivated && m_spBackIcons[kNormal])
		{
			// 处于激活状态但无激活时图片
			DrawImage(hdc, rcReference, kNormal);
		}
		else
		{
			DrawRect(hdc, rcReference, iControlStatus);
		}
	}

	DrawTitle(hdc, rcReference, iControlStatus);
}
